<template>
    <div class="table-container">
        <Header></Header>
        <div class="table-body">
            <el-table
                ref="tableRef"
                v-loading="state.table.loading"
                header-cell-class-name="table-header-cell"
                :default-expand-all="state.table.expandAll"
                :data="state.table.data"
                :row-key="state.getPK()"
                :empty-text="state.table.emptyText"
                :border="state.table.border"
                stripe
                scrollbar-always-on
                @select-all="onSelectAll"
                @select="onSelect"
                @selection-change="onSelectionChange"
                @row-dblclick="state.onTableDblclick">
                <template v-for="(item, key) in state.table.columns">
                    <template v-if="item.show !== false">
                        <Column :key="`${key}'-column'`" :attr="item">
                            <template v-if="item.render" #default="scope">
                                <FieldRender
                                    :key="`${key}-${scope.$index}-${item.render}-${item.prop ? '-' + item.prop + '-' + scope.row[item.prop] : ''}`"
                                    :field="item"
                                    :row="scope.row"
                                    :column="scope.column"
                                    :index="scope.$index"></FieldRender>
                            </template>
                        </Column>
                    </template>
                </template>
            </el-table>
        </div>
        <div class="table-page">
            <el-pagination
                :currentPage="state.page.current"
                :page-size="state.page.size"
                :page-sizes="pageSizes"
                :pager-count="state.page.pager_count"
                background
                :layout="state.page.layout"
                :total="state.page.total_num"
                @size-change="onTableSizeChange"
                @current-change="onTableCurrentChange">
            </el-pagination>
        </div>
    </div>
</template>
<script setup lang="ts">
import { computed, inject, nextTick, ref } from 'vue';
import { TableInstance } from 'element-plus';
import { TableDataState, TableDialogState, TableState } from '@/components/table/table';
import { TableRow } from '@/components/table/index';
import Header from '@/components/table/header/index.vue';
import Column from '@/components/table/column/index.vue';
import FieldRender from '@/components/table/fieldRender/index.vue';

const tableRef = ref<TableInstance>();
const state = inject('state') as TableState<TableDataState, TableDialogState>;

const onTableSizeChange = (val: number) => {
    state.onTableAction('page-size-change', { size: val });
};

const onTableCurrentChange = (val: number) => {
    state.onTableAction('current-page-change', { page: val });
};

const pageSizes = computed(() => {
    let defaultSizes = [10, 20, 50, 100];
    if (state.page?.size) {
        if (!defaultSizes.includes(state.page?.size)) {
            defaultSizes.push(state.page?.size);
        }
    }
    return defaultSizes;
});

/*
 * 全选和取消全选
 * 实现子级同时选择和取消选中
 */
const onSelectAll = (selection: TableRow[]) => {
    if (isSelectAll(selection.map((row: TableRow) => row[state.table.pk!.join('-')].toString()))) {
        // eslint-disable-next-line array-callback-return
        selection.map((row: TableRow) => {
            if (row.children) {
                selectChildren(row.children, true);
            }
        });
    } else {
        tableRef.value?.clearSelection();
    }
};

/*
 * 是否是全选操作
 * 只检查第一个元素是否被选择
 * 全选时：selectIds为所有元素的id
 * 取消全选时：selectIds为所有子元素的id
 */
// @ts-nocheck
const isSelectAll = (selectIds: string[]) => {
    let data = state.table.data as TableRow[];
    let pk = state.table.pk!.join('-');
    let f = false;
    for (const item of data) {
        f = selectIds.includes(item[pk].toString());
        if (f) {
            break;
        }
    }
    return f;
};

/*
 * 选择子项-递归
 */
const selectChildren = (children: TableRow[], type: boolean) => {
    // eslint-disable-next-line array-callback-return
    children.map((j: TableRow) => {
        toggleSelection(j, type);
        if (j.children) {
            selectChildren(j.children, type);
        }
    });
};

/*
 * 执行选择操作
 */
const toggleSelection = (row: TableRow, type: boolean) => {
    if (row) {
        nextTick(() => {
            tableRef.value?.toggleRowSelection(row, type);
        });
    }
};

/*
 * 手动选择时，同时选择子级
 */
const onSelect = (selection: TableRow[], row: TableRow) => {
    if (
        selection.some((item: TableRow) => {
            return row[state.table.pk!.join('-')] === item[state.table.pk!.join('-')];
        })
    ) {
        if (row.children) {
            selectChildren(row.children, true);
        }
    } else {
        if (row.children) {
            selectChildren(row.children, false);
        }
    }
};

/*
 * 记录选择的项
 */
const onSelectionChange = (selection: TableRow[]) => {
    state.onTableAction('selection-change', selection);
};

/*
 * 设置折叠所有-递归
 */
const setUnFoldAll = (children: TableRow[], unfold: boolean) => {
    // eslint-disable-next-line guard-for-in
    for (const key in children) {
        tableRef.value?.toggleRowExpansion(children[key], unfold);
        if (children[key].children) {
            setUnFoldAll(children[key].children!, unfold);
        }
    }
};

/*
 * 折叠所有
 */
const unFoldAll = (unfold: boolean) => {
    setUnFoldAll(state.table.data!, unfold);
};

const getRef = () => {
    return tableRef.value;
};

defineExpose({
    unFoldAll,
    getRef,
});
</script>

<style scoped></style>
